package com.yunhe.authority.service.authority;

import com.yunhe.authority.domain.authority.*;
import com.yunhe.authority.domain.base.Theme;
import com.yunhe.common.exception.*;
import com.yunhe.common.model.PageParam;
import org.springframework.data.domain.Page;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * 用户Service
 * @desc 用户服务类定义
 * @author liuronglei
 */
public interface UserService {

    /**
     * 新增用户
     * @param user 新增对象
     * @param stationId 项目id
     * @param firmId 单位id
     * @param ascriptionOrgId  归属组织单位id
     * @param orgIds  协同组织单位id
     * @param roleIds 角色组织id
     */
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    User createUser(User user, Long stationId, Long firmId, String ascriptionOrgId, String orgIds, String roleIds)
            throws ArgumentErrorException, UniqueConstraintsException, ObjectNotFoundException;

    /**
     * 批量新增用户
     * @param list 用户列表
     */
    @Transactional
    Iterable<User> createUser(List<User> list)
            throws ArgumentErrorException, UniqueConstraintsException, ObjectNotFoundException;

    /**
     * 根据id删除用户
     * @param userIds 用户ID
     */
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    void deleteUser(String userIds) throws UniqueConstraintsException, ArgumentErrorException;

    /**
     * 更新用户
     * @param user 要更新的用户对象
     */
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    User updateUser(User user)
            throws ArgumentErrorException, ObjectNotFoundException, UniqueConstraintsException;

    /**
     * 更新用户
     * @param userId 用户ID
     * @param name 用户名
     * @param title 昵称
     * @param phone 电话
     * @param firmId 单位ID
     * @param homePageId 首页ID
     * @param themeId
     * @param activity 是否可用
     * @param admin
     */
    @Transactional
    User updateUser(Long userId,
                    String name,
                    String title,
                    String phone,
                    Long firmId,
                    Long homePageId,
                    Long themeId,
                    Boolean activity,
                    Boolean admin)
            throws ArgumentErrorException, ObjectNotFoundException, UniqueConstraintsException;

    /**
     * 根据ID获得用户对象
     * @param userId 用户ID
     */
    User findByUserId(Long userId);

    /**
     * 根据用户名获得用户对象
     * @param name 用户名
     */
    User findByName(String name);

    /**
     * 根据用户名和密码获得用户对象
     * @param name 用户名
     * @param password 密码
     */
    User findByNameAndPassword(String name, String password) throws ArgumentErrorException;

    /**
     * 根据条件获得所有用户对象
     * @param userId
     * @param roleId
     * @param name 用户名
     * @param title 昵称
     * @param phone
     * @param pageParam 分页对象
     */
    Iterable<User> getUserByCondition(Long userId,
                                      Long roleId,
                                      String name,
                                      String title,
                                      String phone,
                                      PageParam pageParam);

    Iterable<User> getUserByCondition(String name,
                                      String title,
                                      PageParam pageParam);

    /**
     * 绑定角色
     * @param userId 用户ID
     * @param roleId 角色ID
     */
    @Transactional
    void bindRole(Long userId, Long roleId)
            throws DatabaseProcessException;

    @Transactional
    void updateRoleAdmin(Long id, Long roleId) throws UniqueConstraintsException;

    /**
     * 解绑角色
     * @param userId 用户ID
     * @param roleId 角色ID
     */
    @Transactional
    void unbindRole(Long userId, Long roleId);

    /**
     * 批量更新角色绑定
     * @param userId 用户ID
     * @param roleIdList 角色ID列表
     */
    void updateRole(Long userId, List<Long> roleIdList)
            throws ArgumentErrorException;

    /**
     * 更新首页绑定
     * @param userId 用户ID
     * @param homePageId 首页对象ID
     */
    @Transactional
    void updateHomePage(Long userId, Long homePageId)
            throws ObjectNotFoundException;

    /**
     * 更新主题绑定
     * @param userId 用户ID
     * @param themeId 主题对象ID
     */
    @Transactional
    void updateTheme(Long userId, Long themeId)
            throws ObjectNotFoundException;

    /**
     * 获得用户绑定的角色列表
     * @param userId 用户ID
     */
    Iterable<Role> findRolesByUserId(Long userId);

    /**
     * 获得用户有权限的菜单列表
     * @param userId 用户ID
     */
    Iterable<Menu> findMenusByUserId(Long userId);

    /**
     * 获得用户有权限的app菜单列表
     * @param userId 用户ID
     */
    //Iterable<Menu> findAppMenusByUserId(Long userId);

    /**
     * 获得用户绑定的首先
     * @param userId 用户ID
     */
    HomePage findHomePageByUserId(Long userId);

    /**
     * 根据服务名获得用户联系方式
     * @param serviceName 服务名称
     */
    Iterable<String> findUserPhoneByServiceName(String serviceName);

    /**
     * 根据用户ID获得主题
     * @param id 用户ID
     */
    Theme findThemeByUserId(Long id);

    /**
     * 修改密码
     * @param id 用户ID
     * @param password 用户密码
     */
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    User updatePassword(Long id, String phone, String password, String newPassword)
            throws UsernamePasswordException;

    List<User> resetPassword(String ids) throws UsernamePasswordException, ArgumentErrorException;

    String getPasswordByUsername(String username);

    Iterable<User> findUsersByRoleId(Long roleId, Long userId);

    void sendValidateMsg(String phone, String type) throws ArgumentErrorException;

    String getValidateCode(String phone) throws ArgumentErrorException;

    User verification(String name, String password) throws ArgumentErrorException;

    void verification(Long userId, String key, Boolean agree) throws IOException;

    Map<String, Object> getVerificationResult(String key) throws IOException;

    List<User> findUsersByMenu(String menuName);
    /**
     * 根据姓名获得用户列表
     * @param title 姓名
     */
    Iterable<User> findByTitleContaining(String title);

    /**
     * 根据账号列表获得用户列表
     * @param nameList 账号列表
     */
    Iterable<User> findUsersByNames(List<String> nameList);

    Iterable<User> findByMenuName(String menuName);

    /**
     * 根据单位id查询用户列表
     * @param firmId 单位ID
     * @param queryData 查询条件
     * @param pageParam 分页对象
     * @return
     */
    Page<User> findUsersByFirmId(Long firmId, String queryData, PageParam pageParam);

    /**
     * 获得所有企业的用户列表
     * @param queryData 查询条件
     * @param pageParam 分页对象
     * @return
     */
    Page<User> getAllCompanyUser(String queryData, PageParam pageParam);

    User findByPhoneAndPassword(String phone, String password) throws ArgumentErrorException, UsernamePasswordException;

    User getUserByPhone(String phone) throws ObjectNotFoundException;

    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    void saveLoginRecord(User user);

    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    User changePassword(String phone, String verificationCode, String password) throws ArgumentErrorException;

    User findByPhoneAndVerificationCode(String phone, String verificationCode) throws ArgumentErrorException, UsernamePasswordException;

    /**
     * 根据条件查询用户列表
     * @param phone
     * @param title
     * @param mail
     * @param activity
     * @param createStartTime
     * @param createEndTime
     * @param creator
     * @param lastLoginStartTime
     * @param lastLoginEndTime
     * @param lastLoginSystem
     * @param pageParam
     * @return
     */
    Iterable<User> getUserByCondition(String phone, String title, String mail, String activity,
                                      String createStartTime, String createEndTime, String creator,
                                      String lastLoginStartTime, String lastLoginEndTime,
                                      String lastLoginSystem, PageParam pageParam);

    /**
     * 禁用/恢复账号
     * @param ids
     * @param activity
     * @param headerUser
     * @param headerBackUser
     */
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    void disableRecoveryUser(String ids, String activity, User headerUser,BackUser headerBackUser) throws ArgumentErrorException;

    /**
     * 判断是否是重置面第一次登录
     * @param id
     * @return
     */
    Boolean resetFirstLogin(Long id);

    /**
     * 关联项目
     * @param id
     * @param firmIds
     * @param stationIds
     * @param ascriptionOrgIds
     * @param orgIds
     * @param roleIds
     * @throws ArgumentErrorException
     * @throws ObjectNotFoundException
     */
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    void bindProejctRoleOrg(Long id, Long firmIds, Long stationIds, String ascriptionOrgIds, String orgIds, String roleIds) throws ArgumentErrorException, ObjectNotFoundException;

    /**
     * 通过用户id 查询关联项目列表
     * @param id
     * @param type
     * @param keywords
     * @param pageParam
     * @return
     */
    Iterable<ProjectUser> getUser(Long id, String type, String keywords, PageParam pageParam) throws ArgumentErrorException;

    /**
     * 解绑用户与单位项目的关系
     * @param id
     * @param stationId
     * @param firmId
     */
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    void unbindUser(Long id, Long stationId, Long firmId) throws ObjectNotFoundException, ArgumentErrorException, UniqueConstraintsException;

    /**
     * 通过角色查询用户信息
     * @param roleType
     * @return
     */
    List<User> getUserByRoleType(String roleType);

    /**
     * 根据单位id或项目id获取用户信息
     * @param firmId
     * @param stationId
     * @param roleTitle
     * @param pageParam
     * @return
     */
    Iterable<EmployeeUser> getUserByCondition(Long firmId, Long stationId, String roleTitle, PageParam pageParam) throws ArgumentErrorException;

    /**
     * 禁用项目用户
     * @param ids
     * @param firmId
     * @param stationId
     * @param activity
     * @param headerUser
     */
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    void disableRecoveryProjectUser(String ids, Long firmId, Long stationId, String activity, User headerUser) throws ArgumentErrorException;

    /**
     * 查看项目/单位用户详情
     * @param id
     * @param firmId
     * @param stationId
     * @return
     */
    EmployeeUser getProjectUserById(Long id, Long firmId, Long stationId);

    /**
     * 查询用户
     * @param id 角色id
     * @param stationId 虚拟园区id
     * @param firmId 单位id
     * @param keywords 关键词
     * @param pageParam 分页
     * @return Page
     */
    Page<EmployeeUser> getUserByStationIdOrFirmId(Long id, Long stationId, Long firmId, String keywords, PageParam pageParam);

    /**
     * 编辑单位/项目用户
     * @param id
     * @param firmId
     * @param stationId
     * @param roleIds
     * @param ascriptionOrgIds
     * @param orgIds
     * @param activity
     * @param headerUser
     * @param headerBackUser
     * @param user
     */
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    void updateProjectUserById(Long id, Long firmId, Long stationId,
                               String roleIds, String ascriptionOrgIds, String orgIds,
                               String activity, User headerUser,BackUser headerBackUser, User user) throws ArgumentErrorException, UniqueConstraintsException, ObjectNotFoundException;

    /**
     * 删除单位/项目用户信息
     * @param ids
     * @param firmId
     * @param stationId
     */
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    void unbindProejctUser(String ids, Long firmId, Long stationId) throws ArgumentErrorException, ObjectNotFoundException, UniqueConstraintsException;

    /**
     * 新增单位/项目用户信息
     * @param firmId
     * @param stationId
     * @param ascriptionOrgIds
     * @param orgIds
     * @param roleIds
     * @param user
     */
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    void addProjectUser(Long firmId, Long stationId, String ascriptionOrgIds, String orgIds, String roleIds, User user) throws ArgumentErrorException, ObjectNotFoundException, UniqueConstraintsException;

    /**
     * 记录当前登录人所选的项目信息
     * @param id
     * @param projectId
     * @param projectFlag
     */
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    void updateLastProejct(Long id, Long projectId,String projectFlag);

    /**
     * 根据部门查询指定角色的人员信息
     * @param orgId
     * @param roleName
     * @param stationId
     * @param firmId
     * @return
     */
    List<UserProjectOrg> getUserByOrgAndRoleName(Long orgId, String roleName, Long stationId, Long firmId);

    /**
     * 根据部门查询指定角色的人员信息
     * @param orgIds
     * @param roleName
     * @param stationId
     * @return
     */
    List<Map<String,Object>> getUserByStationIdAndOrg(List<Long> orgIds, String roleName, Long stationId);

    /**
     * 修改面
     * @param changePassword
     * @return
     */
    User updatePasswordByValidateCode(ChangePassword changePassword) throws UsernamePasswordException, ArgumentErrorException;

    User findByUserIdAndStationId(Long id, Long stationId);

    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    void unbindUserAndRole(Long roleId, Long userId);

    User findByPhoneAndDecodePassword(String phone, String password);

    List<Map<String,Object>> getUserByOrgId(Long orgId) throws ArgumentErrorException;

    void    validateByWeChat(String phone, String type) throws ArgumentErrorException;

    String checkVerificationCode(String phone, String verificationCode) throws ArgumentErrorException;

    void validateForMob(String phone, String type) throws ArgumentErrorException;

    User findByPhoneAndVerificationCodeforMob(String phone, String verificationCode) throws ArgumentErrorException, UsernamePasswordException;

    User changePasswordForMob(String phone, String verificationCode, String password) throws ArgumentErrorException;

    List<User> findStationUserByStationId(Long stationId);

    List<UserProjectOrg> getUserByOrgIdAndStationId(Long orgId, Long stationId);

    User getLoginUserByPhone(String phone) throws ArgumentErrorException;

    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    void disableRecoveryProjectBackUser(String ids, Long firmId, Long stationId, String activity, BackUser headerBackUser) throws ArgumentErrorException;

    List<User> findStationUserByQueryCondition(String userName) throws ArgumentErrorException;



    /*
    void unbindAllRoles(Long userId)
            throws DatabaseProcessException;

    void unbindRoles(Long userId, List<Long> roleIdList)
            throws DatabaseProcessException;
    */

}
